package Raid;

import org.lwjgl.opengl.GL11;
import org.newdawn.slick.geom.*;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.geom.ShapeRenderer;
import java.util.ArrayList;



public class Palo {

	double x;
	double y;
	double width;
	double height;
	double maskWidth;
	double maskHeight;
	
	double xSpeed = 0;
	double ySpeed = 0;
	double maxYSpeed = 0.3;
	double gravity = 0.0009;
	
	double diggingPower = 0.05;
	
	int jumpSpacing = 450;
	int timeSinceJump = jumpSpacing+1;
	int maxJumps = 2;
	int jumps = 0;
	
	double walkingSpeed = 0.1;
	int[] walking = {0, 0};
	
	int facing = -1;  // -1: left, 0: up, 1: right
	int lastFacing = -1;
	boolean standing = false;
	boolean lookingUp = false;
	boolean jumping = false;
	boolean digging = false;
	
	
	Laser[] lasers = {null, null, null, null, null, null, null, null};
	
	
	
	Environment env;
	
	Rectangle mask;
	
	Texture texture;	
	
	public Palo(Environment env, double startX, double startY){
		x = startX;
		y = startY;
		width = 16;
		height = 16;
		maskWidth = 12;
		maskHeight = 16;
		this.env = env;
		mask = new Rectangle((float)(x-maskWidth/2), (float)y, (float)(maskWidth), (float)maskHeight);

	}
	
	public void doLogic(int delta){
		updateMovement(delta);
		updatePhysics(delta);
		calcFacing();
		mask.setLocation((float)(x - maskWidth/2), (float)y);
		jumpLogic(delta);
		updateLasers(delta);
	}
	
	
	
	
	public void updatePhysics(int delta){
		fallingPhysics(delta);
		horizontalPhysics(delta);
		
		if (ySpeed > maxYSpeed){
			ySpeed = maxYSpeed;
		}
		
		x += xSpeed*delta;
		y += ySpeed*delta;
		if (x > Raid.windowWidth){
			x = Raid.windowWidth;
		} else if (x < 0){
			x = 0;
		}
		if (y > Raid.windowHeight){
			y = Raid.windowHeight;
		} else if (y < 0){
			y = 0;
		}
		
	}
	
	
	public void updateMovement(int delta){
		xSpeed = walkingSpeed*walking[0] + walkingSpeed*walking[1];
	}
	
	public void fallingPhysics(int delta){
		ySpeed += gravity*delta;
		standing = false;
		Rectangle newMask = getMask(0, (float)ySpeed);
		if (ySpeed > 0){
			Block[] beneathBlocks = env.getBeneathBlocks(x, y, width);
			for (int i = 0; i < 3; i++){
				if (beneathBlocks[i] != null && beneathBlocks[i].solid && beneathBlocks[i].mask.getMinY() - newMask.getMinY() > 8 
						&& Utils.intersects(beneathBlocks[i].mask, newMask)){
					ySpeed = 0;
					y = beneathBlocks[i].y - width;
					standing = true;
					jumps = 0;
					break;
				}
			}
		} else if (ySpeed < 0){
			Block[] aboveBlocks = env.getAboveBlocks(x, y, width);
			for (int i = 0; i < 6; i++){
				if (aboveBlocks[i] != null && aboveBlocks[i].solid 
						&& Utils.intersects(aboveBlocks[i].mask, newMask)){
					ySpeed = 0;
					y = aboveBlocks[i].y + Block.width;
					break;
				}
			}
		}
	}
	
	
	public void updateLasers(int delta){
		for (int i = 0; i < lasers.length; i++){
			if (lasers[i] != null){
				lasers[i].doLogic(delta);
				if (lasers[i].age >= Laser.laserLife){
					lasers[i] = null;
				}
			}
		}
		laserCollisions();
	}
	
	
	
	public void horizontalPhysics(int delta){
		Block[] sideBlocks = env.getSideBlocks(x, y, width);
		Rectangle newMask = getMask((float)xSpeed, 0f);
		if (xSpeed > 0){
			for (int i = 1; i < 6; i+=2){
				if (sideBlocks[i] != null && sideBlocks[i].solid && Utils.intersects(sideBlocks[i].mask, newMask)){
					xSpeed = 0;
					x = sideBlocks[i].x - mask.getWidth()/2.0f;
					dig(sideBlocks[i], delta);
					break;
				}
			}
		} else if (xSpeed < 0) {
			for (int i = 0; i < 6; i+=2){
				if (sideBlocks[i] != null && sideBlocks[i].solid && Utils.intersects(sideBlocks[i].mask, newMask)){
					xSpeed = 0;
					x = sideBlocks[i].x + Block.width + mask.getWidth()/2.0f;
					dig(sideBlocks[i], delta);
					break;
				}
			}
		}
	}
	
	public void dig(Block block, int delta){
		if (standing == true){
			env.damageBlock(block.x, block.y, diggingPower*delta);
		}
	}
	
	
	
	public Rectangle getMask(float xs, float ys){
		return new Rectangle((float)(x-maskWidth/2) + xs, (float)y + ys, (float)(maskWidth), (float)maskHeight);
	}
	
	
	
	
	public void jump(boolean i){
		jumping = i;
	}
	
	public void jumpLogic(int delta){
		if (jumping == true){
			if (timeSinceJump >= jumpSpacing && jumps < maxJumps){
				ySpeed = -maxYSpeed;
				timeSinceJump = 0;
				jumps += 1;
			}
		}
		
		timeSinceJump += delta;
		if (timeSinceJump > 50000){
			timeSinceJump = jumpSpacing+1;
		}
	}
	
	
	
	public void walkRight(int motion){
		walking[1] = motion;
	}
	
	public void walkLeft(int motion){
		walking[0] = motion;
	}
	
	public void shootLaser(int mouseX, int mouseY){
		//System.out.println("Mouse at X:" + mouseX + " Y:" + mouseY);
		//System.out.println("Palo at X:" + x + " Y:" + y);
		for (int i = 0; i < lasers.length; i++){
			if (lasers[i] == null){
				float a = (float)x-(float)mouseX;
				float o = (float)y-(float)mouseY;
				double theta =  Math.atan((double)(o/a));
				float xs = (float)Math.cos(theta);
				if (a < 0){
					xs = Math.abs(xs);
				}
				else{
					xs = -Math.abs(xs);
				}
				float ys = (float)Math.sin(theta);
				if (o < 0){
					ys = Math.abs(ys);
				}
				else{
					ys = -Math.abs(ys);
				}
				//if (facing == 0){
				//	ys = -1f;
				//}
				lasers[i] = new Laser(env, (float)x, (float)y, xs, ys, i);
				break;
			}
		}
	}
	
	public void laserCollisions(){
		for (int i = 0; i < lasers.length; i++){
			if (lasers[i] != null){
				Block[] surroundingBlocks = env.getSurroundingBlocks(lasers[i].x, lasers[i].y, lasers[i].width);
				for (int j = 0; j < surroundingBlocks.length; j++){
					if (surroundingBlocks[j] != null && surroundingBlocks[j].solid == true && lasers[i].mask.intersects(surroundingBlocks[j].mask)){
						env.damageBlock(surroundingBlocks[j].x, surroundingBlocks[j].y, lasers[i].damage);
						lasers[i].age += 200;
						break;
					}
				}
			}
		}
		
		ArrayList<Baddy> r = new ArrayList<Baddy>();
		for (int i = 0; i < lasers.length; i++){
			if (lasers[i] != null){
				for (Baddy b: env.baddies){
					if (lasers[i].mask.intersects(b.mask)){
						if (b.takeDamage(lasers[i].damage) == true){
							r.add(b);
						}
						lasers[i] = null;
						break;
					}
				}
			}
		}
		
		for (Baddy b: r){
			env.baddies.remove(b);
		}
		
	}
	
	
	public void calcFacing(){
		if (lookingUp == false){
			if (xSpeed > 0){
				facing = 1;
			} else if (xSpeed < 0){
				facing = -1;
			} else {
				facing = lastFacing;
			}
		} else {
			facing = 0;
		}
	}
	
	
	public void render(){
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
		texture.bind();
		GL11.glBegin(GL11.GL_QUADS);
			GL11.glNormal3d(0, 0, 1);
			GL11.glTexCoord2d(0.0, 0.0);
			GL11.glVertex3i((int)(x-width/2), (int)y, 0);
			GL11.glTexCoord2d(1.0, 0.0);
			GL11.glVertex3i((int)(x+width/2), (int)y, 0);
			GL11.glTexCoord2d(1.0, 1.0);
			GL11.glVertex3i((int)(x+width/2), (int)(y+width), 0);
			GL11.glTexCoord2d(0.0, 1.0);
			GL11.glVertex3d((int)(x-width/2), (int)(y+width), 0);
		GL11.glEnd();
		
		for (int i = 0; i < lasers.length; i++){
			if (lasers[i] != null) {
				lasers[i].render();
			}
		}
		
		
	}
	
	
	
	
	
	
	
}
